#ifndef TESTBSTRANGE_HPP
#define TESTBSTRANGE_HPP
#include "BinarySearchTree.h"
#include <vector>
#include <ctime>

/**
 * @brief Disorder a vector. (Availble in a for-loop)
 * @tparam DT 
 * @param  _arr             The vector to be disordered.
 * @param  manual_seed      A manual factor to generate different random seeds in a for-loop.
 */
template <typename DT>
inline void DisorderVector(std::vector<DT> &_arr,unsigned int manual_seed = 0)
{
    srand((unsigned int) time(NULL)+manual_seed);
    random_shuffle(_arr.begin(), _arr.end());
}

/**
 * @brief Generate a random integer in [0,N-1]. (Available in a for-loop)
 * @param  N               
 * @param  manual_seed     A manual factor to generate different random seeds in a for-loop. 
 */
inline int RandomInt(int N, unsigned int manual_seed = 0)
{
    srand((unsigned int) time(NULL)+manual_seed);
    return rand()%N;
}

/**
 * @brief Initialize a random BST ranging from [0,N-1]. (Available in a for-loop)
 * @param  pbst             
 * @param  N               
 * @param  manual_seed      A manual factor to generate different random seeds in a for-loop. 
 */
void RandomInitializeBST(BinarySearchTree<int> *pbst, int N, unsigned int manual_seed = 0)
{
    std::vector<int> Vec;
    Vec.reserve(N);
    for (int i = N; i > 0; i--)
        Vec.push_back(i);
    DisorderVector(Vec,manual_seed);
    pbst->makeEmpty();
    for (auto i:Vec)
        pbst->insert(i);
}

/**
 * @brief A simple test for search-range function.
 * @param  pbst             My Param doc
 * @param  inf              The inf of range.
 * @param  sup              The sup of range.
 * @param  displayResult    Whether to display the search-range result.
 * @return Total time cosumed by search-range, the time unit is 'second'.
 */
double testBSTRange(BinarySearchTree<int> *pbst,const int inf,const int sup, bool displayResult = false)
{
    clock_t start, end;
    std::vector<int> vec;
    if(displayResult)
    {
    std::cout<< "BST member in ["<<inf<<", "<<sup<<"]:\n"; 
    }
    start = clock();
    pbst->searchRange(inf,sup,vec);
    end = clock();
    if(displayResult)
    {
        for(auto i:vec)
            std::cout << i << '\t';
        std::cout<< '\n';
    }
    return double(end - start) / CLOCKS_PER_SEC;
}

#endif 